{
 "cells": [
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Jupyter Introduction "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "First and foremost, the Jupyter Notebook is an interactive environment for writing and running code. The notebook is capable of running code in a wide range of languages. However, each notebook is associated with a single kernel.  This notebook is associated with the IPython kernel, therefor runs Python code."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Code cells allow you to enter and run code"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Run a code cell using `Shift-Enter` or pressing the <button class='btn btn-default btn-xs'><i class=\"icon-step-forward fa fa-step-forward\"></i></button> button in the toolbar above:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:43.831893Z",
     "start_time": "2019-07-30T19:53:43.821327Z"
    }
   },
   "outputs": [],
   "source": [
    "a = 10"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:43.892853Z",
     "start_time": "2019-07-30T19:53:43.850185Z"
    }
   },
   "outputs": [],
   "source": [
    "print(a)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "There are two other keyboard shortcuts for running code:\n",
    "\n",
    "* `Alt-Enter` runs the current cell and inserts a new one below.\n",
    "* `Ctrl-Enter` run the current cell and enters command mode."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Managing the Kernel"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Code is run in a separate process called the Kernel.  The Kernel can be interrupted or restarted.  Try running the following cell and then hit the <button class='btn btn-default btn-xs'><i class='icon-stop fa fa-stop'></i></button> button in the toolbar above."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:53.931859Z",
     "start_time": "2019-07-30T19:53:43.909540Z"
    }
   },
   "outputs": [],
   "source": [
    "import time\n",
    "time.sleep(10)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If the Kernel dies you will be prompted to restart it. Here we call the low-level system libc.time routine with the wrong argument via\n",
    "ctypes to segfault the Python interpreter:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:53.951811Z",
     "start_time": "2019-07-30T19:53:53.941663Z"
    }
   },
   "outputs": [],
   "source": [
    "import sys\n",
    "from ctypes import CDLL\n",
    "# This will crash a Linux or Mac system\n",
    "# equivalent calls can be made on Windows\n",
    "\n",
    "# Uncomment these lines if you would like to see the segfault\n",
    "\n",
    "# dll = 'dylib' if sys.platform == 'darwin' else 'so.6'\n",
    "# libc = CDLL(\"libc.%s\" % dll) \n",
    "# libc.time(-1)  # BOOM!!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Cell menu"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The \"Cell\" menu has a number of menu items for running code in different ways. These includes:\n",
    "\n",
    "* Run and Select Below\n",
    "* Run and Insert Below\n",
    "* Run All\n",
    "* Run All Above\n",
    "* Run All Below"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Restarting the kernels"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The kernel maintains the state of a notebook's computations. You can reset this state by restarting the kernel. This is done by clicking on the <button class='btn btn-default btn-xs'><i class='fa fa-repeat icon-repeat'></i></button> in the toolbar above."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## sys.stdout and sys.stderr"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The stdout and stderr streams are displayed as text in the output area."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:53.980000Z",
     "start_time": "2019-07-30T19:53:53.960020Z"
    }
   },
   "outputs": [],
   "source": [
    "print(\"hi, stdout\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:54.007098Z",
     "start_time": "2019-07-30T19:53:53.988217Z"
    }
   },
   "outputs": [],
   "source": [
    "from __future__ import print_function\n",
    "print('hi, stderr', file=sys.stderr)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Output is asynchronous"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "All output is displayed asynchronously as it is generated in the Kernel. If you execute the next cell, you will see the output one piece at a time, not all at the end."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.122387Z",
     "start_time": "2019-07-30T19:53:54.022166Z"
    }
   },
   "outputs": [],
   "source": [
    "import time, sys\n",
    "for i in range(8):\n",
    "    print(i)\n",
    "    time.sleep(0.5)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Large outputs"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To better handle large outputs, the output area can be collapsed. Run the following cell and then single- or double- click on the active area to the left of the output:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.145444Z",
     "start_time": "2019-07-30T19:53:58.128413Z"
    }
   },
   "outputs": [],
   "source": [
    "for i in range(50):\n",
    "    print(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Beyond a certain point, output will scroll automatically:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.229485Z",
     "start_time": "2019-07-30T19:53:58.151964Z"
    }
   },
   "outputs": [],
   "source": [
    "for i in range(500):\n",
    "    print(2**i - 1)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Markdown Cells"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Text can be added to IPython Notebooks using Markdown cells.  Markdown is a popular markup language that is a superset of HTML. Its specification can be found here:\n",
    "\n",
    "<http://daringfireball.net/projects/markdown/>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Markdown basics"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can make text *italic* or **bold**."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can build nested itemized or enumerated lists:\n",
    "\n",
    "* One\n",
    "    - Sublist\n",
    "        - This\n",
    "  - Sublist\n",
    "        - That\n",
    "        - The other thing\n",
    "* Two\n",
    "  - Sublist\n",
    "* Three\n",
    "  - Sublist\n",
    "\n",
    "Now another list:\n",
    "\n",
    "1. Here we go\n",
    "    1. Sublist\n",
    "    2. Sublist\n",
    "2. There we go\n",
    "3. Now this"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can add horizontal rules:\n",
    "\n",
    "---"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is a blockquote:\n",
    "\n",
    "> Beautiful is better than ugly.\n",
    "> Explicit is better than implicit.\n",
    "> Simple is better than complex.\n",
    "> Complex is better than complicated.\n",
    "> Flat is better than nested.\n",
    "> Sparse is better than dense.\n",
    "> Readability counts.\n",
    "> Special cases aren't special enough to break the rules.\n",
    "> Although practicality beats purity.\n",
    "> Errors should never pass silently.\n",
    "> Unless explicitly silenced.\n",
    "> In the face of ambiguity, refuse the temptation to guess.\n",
    "> There should be one-- and preferably only one --obvious way to do it.\n",
    "> Although that way may not be obvious at first unless you're Dutch.\n",
    "> Now is better than never.\n",
    "> Although never is often better than *right* now.\n",
    "> If the implementation is hard to explain, it's a bad idea.\n",
    "> If the implementation is easy to explain, it may be a good idea.\n",
    "> Namespaces are one honking great idea -- let's do more of those!"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "And shorthand for links:\n",
    "\n",
    "[IPython's website](http://ipython.org)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Headings"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you want, you can add headings using Markdown's syntax:\n",
    "\n",
    "```\n",
    "# Heading 1\n",
    "# Heading 2\n",
    "## Heading 2.1\n",
    "## Heading 2.2\n",
    "```"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "**BUT most of the time you should use the Notebook's Heading Cells to organize your Notebook content**, as they provide meaningful structure that can be interpreted by other tools, not just large bold fonts."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Embedded code"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can embed code meant for illustration instead of execution in Python:\n",
    "\n",
    "    def f(x):\n",
    "        \"\"\"a docstring\"\"\"\n",
    "        return x**2\n",
    "\n",
    "or other languages:\n",
    "\n",
    "    if (i=0; i<n; i++) {\n",
    "      printf(\"hello %d\\n\", i);\n",
    "      x += 4;\n",
    "    }"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### LaTeX equations"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Courtesy of MathJax, you can include mathematical expressions both inline: \n",
    "$e^{i\\pi} + 1 = 0$  and displayed:\n",
    "\n",
    "$$e^x=\\sum_{i=0}^\\infty \\frac{1}{i!}x^i$$"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Github flavored markdown (GFM)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Notebook webapp support Github flavored markdown meaning that you can use triple backticks for code blocks \n",
    "<pre>\n",
    "```python\n",
    "print \"Hello World\"\n",
    "```\n",
    "\n",
    "```javascript\n",
    "console.log(\"Hello World\")\n",
    "```\n",
    "</pre>\n",
    "\n",
    "Gives \n",
    "```python\n",
    "print \"Hello World\"\n",
    "```\n",
    "\n",
    "```javascript\n",
    "console.log(\"Hello World\")\n",
    "```\n",
    "\n",
    "And a table like this : \n",
    "\n",
    "<pre>\n",
    "| This | is   |\n",
    "|------|------|\n",
    "|   a  | table| \n",
    "</pre>\n",
    "\n",
    "A nice Html Table\n",
    "\n",
    "| This | is   |\n",
    "|------|------|\n",
    "|   a  | table| "
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### General HTML"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Because Markdown is a superset of HTML you can even add things like HTML tables:\n",
    "\n",
    "<table>\n",
    "<tr>\n",
    "<th>Header 1</th>\n",
    "<th>Header 2</th>\n",
    "</tr>\n",
    "<tr>\n",
    "<td>row 1, cell 1</td>\n",
    "<td>row 1, cell 2</td>\n",
    "</tr>\n",
    "<tr>\n",
    "<td>row 2, cell 1</td>\n",
    "<td>row 2, cell 2</td>\n",
    "</tr>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Local files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "If you have local files in your Notebook directory, you can refer to these files in Markdown cells directly:\n",
    "\n",
    "    [subdirectory/]<filename>\n",
    "\n",
    "For example, in the images folder, we have the Python logo:\n",
    "\n",
    "    <img src=\"images/jupyter-basics-python-logo.svg\" />\n",
    "\n",
    "<img src=\"images/jupyter-basics-python-logo.svg\" />\n",
    "\n",
    "and a video with the HTML5 video tag:\n",
    "\n",
    "    <video controls src=\"images/jupyter-basics-animation.m4v\" />\n",
    "\n",
    "<video controls src=\"images/jupyter-basics-animation.m4v\" />\n",
    "\n",
    "These do not embed the data into the notebook file, and require that the files exist when you are viewing the notebook."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Security of local files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Note that this means that the IPython notebook server also acts as a generic file server\n",
    "for files inside the same tree as your notebooks.  Access is not granted outside the\n",
    "notebook folder so you have strict control over what files are visible, but for this\n",
    "reason it is highly recommended that you do not run the notebook server with a notebook\n",
    "directory at a high level in your filesystem (e.g. your home directory).\n",
    "\n",
    "When you run the notebook in a password-protected manner, local file access is restricted\n",
    "to authenticated users unless read-only views are active."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Rich Output"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In Python, objects can declare their textual representation using the `__repr__` method.  IPython expands on this idea and allows objects to declare other, rich representations including:\n",
    "\n",
    "* HTML\n",
    "* JSON\n",
    "* PNG\n",
    "* JPEG\n",
    "* SVG\n",
    "* LaTeX\n",
    "\n",
    "A single object can declare some or all of these representations; all are handled by IPython's *display system*. This Notebook shows how you can use this display system to incorporate a broad range of content into your Notebooks."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Basic display imports"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The `display` function is a general purpose tool for displaying different representations of objects. Think of it as `print` for these rich representations."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.248472Z",
     "start_time": "2019-07-30T19:53:58.234406Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import display"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A few points:\n",
    "\n",
    "* Calling `display` on an object will send **all** possible representations to the Notebook.\n",
    "* These representations are stored in the Notebook document.\n",
    "* In general the Notebook will use the richest available representation.\n",
    "\n",
    "If you want to display a particular representation, there are specific functions for that:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.273617Z",
     "start_time": "2019-07-30T19:53:58.258019Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import (\n",
    "    display_pretty, display_html, display_jpeg,\n",
    "    display_png, display_json, display_latex, display_svg\n",
    ")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Images"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "To work with images (JPEG, PNG) use the `Image` class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.315992Z",
     "start_time": "2019-07-30T19:53:58.277400Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import Image"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.383159Z",
     "start_time": "2019-07-30T19:53:58.344650Z"
    }
   },
   "outputs": [],
   "source": [
    "i = Image(filename='images/jupyter-basics-logo.png')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Returning an `Image` object from an expression will automatically display it:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.408667Z",
     "start_time": "2019-07-30T19:53:58.388847Z"
    }
   },
   "outputs": [],
   "source": [
    "i"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or you can pass an object with a rich representation to `display`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.440219Z",
     "start_time": "2019-07-30T19:53:58.415802Z"
    }
   },
   "outputs": [],
   "source": [
    "display(i)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "An image can also be displayed from raw data or a URL."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.506425Z",
     "start_time": "2019-07-30T19:53:58.456911Z"
    }
   },
   "outputs": [],
   "source": [
    "Image(url='http://python.org/images/python-logo.gif')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "SVG images are also supported out of the box."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:53:58.577526Z",
     "start_time": "2019-07-30T19:53:58.511856Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import SVG\n",
    "SVG(filename='images/jupyter-basics-python-logo.svg')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### Embedded vs non-embedded Images"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "By default, image data is embedded in the notebook document so that the images can be viewed offline. However it is also possible to tell the `Image` class to only store a *link* to the image. Let's see how this works using a webcam at Berkeley."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.268238Z",
     "start_time": "2019-07-30T19:53:58.587172Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import Image\n",
    "img_url = 'http://www.lawrencehallofscience.org/static/scienceview/scienceview.berkeley.edu/html/view/view_assets/images/newview.jpg'\n",
    "\n",
    "# by default Image data are embedded\n",
    "Embed      = Image(img_url)\n",
    "\n",
    "# if kwarg `url` is given, the embedding is assumed to be false\n",
    "SoftLinked = Image(url=img_url)\n",
    "\n",
    "# In each case, embed can be specified explicitly with the `embed` kwarg\n",
    "# ForceEmbed = Image(url=img_url, embed=True)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is the embedded version. Note that this image was pulled from the webcam when this code cell was originally run and stored in the Notebook. Unless we rerun this cell, this is not todays image."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.334079Z",
     "start_time": "2019-07-30T19:54:00.271732Z"
    }
   },
   "outputs": [],
   "source": [
    "Embed"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is today's image from same webcam at Berkeley, (refreshed every minutes, if you reload the notebook), visible only with an active internet connection, that should be different from the previous one. Notebooks saved with this kind of image will be smaller and always reflect the current version of the source, but the image won't display offline."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.369747Z",
     "start_time": "2019-07-30T19:54:00.347912Z"
    }
   },
   "outputs": [],
   "source": [
    "SoftLinked"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Of course, if you re-run this Notebook, the two images will be the same again."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## HTML"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Python objects can declare HTML representations that will be displayed in the Notebook. If you have some HTML you want to display, simply use the `HTML` class."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.390660Z",
     "start_time": "2019-07-30T19:54:00.376193Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import HTML"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.424583Z",
     "start_time": "2019-07-30T19:54:00.397335Z"
    }
   },
   "outputs": [],
   "source": [
    "s = \"\"\"<table>\n",
    "<tr>\n",
    "<th>Header 1</th>\n",
    "<th>Header 2</th>\n",
    "</tr>\n",
    "<tr>\n",
    "<td>row 1, cell 1</td>\n",
    "<td>row 1, cell 2</td>\n",
    "</tr>\n",
    "<tr>\n",
    "<td>row 2, cell 1</td>\n",
    "<td>row 2, cell 2</td>\n",
    "</tr>\n",
    "</table>\"\"\""
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.452069Z",
     "start_time": "2019-07-30T19:54:00.442050Z"
    }
   },
   "outputs": [],
   "source": [
    "h = HTML(s)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.485649Z",
     "start_time": "2019-07-30T19:54:00.467827Z"
    }
   },
   "outputs": [],
   "source": [
    "display(h)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can also use the `%%html` cell magic to accomplish the same thing."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.510966Z",
     "start_time": "2019-07-30T19:54:00.492534Z"
    }
   },
   "outputs": [],
   "source": [
    "%%html\n",
    "<table>\n",
    "<tr>\n",
    "<th>Header 1</th>\n",
    "<th>Header 2</th>\n",
    "</tr>\n",
    "<tr>\n",
    "<td>row 1, cell 1</td>\n",
    "<td>row 1, cell 2</td>\n",
    "</tr>\n",
    "<tr>\n",
    "<td>row 2, cell 1</td>\n",
    "<td>row 2, cell 2</td>\n",
    "</tr>\n",
    "</table>"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## JavaScript"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The Notebook also enables objects to declare a JavaScript representation. At first, this may seem odd as  output is inherently visual and JavaScript is a programming language. However, this opens the door for rich output that leverages the full power of JavaScript and associated libraries such as [d3.js](http://d3js.org) for output."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.520661Z",
     "start_time": "2019-07-30T19:54:00.515899Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import Javascript"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Pass a string of JavaScript source code to the `JavaScript` object and then display it."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.534879Z",
     "start_time": "2019-07-30T19:54:00.525981Z"
    }
   },
   "outputs": [],
   "source": [
    "js = Javascript('alert(\"hi\")');"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.548705Z",
     "start_time": "2019-07-30T19:54:00.540176Z"
    }
   },
   "outputs": [],
   "source": [
    "display(js)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The same thing can be accomplished using the `%%javascript` cell magic:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.576330Z",
     "start_time": "2019-07-30T19:54:00.558692Z"
    }
   },
   "outputs": [],
   "source": [
    "%%javascript\n",
    "\n",
    "alert(\"hi\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here is a more complicated example that loads `d3.js` from a CDN, uses the `%%html` magic to load CSS styles onto the page and then runs ones of the `d3.js` examples."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.594786Z",
     "start_time": "2019-07-30T19:54:00.582884Z"
    }
   },
   "outputs": [],
   "source": [
    "Javascript(\n",
    "    \"\"\"$.getScript('//cdnjs.cloudflare.com/ajax/libs/d3/3.2.2/d3.v3.min.js')\"\"\"\n",
    ")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.613066Z",
     "start_time": "2019-07-30T19:54:00.600154Z"
    }
   },
   "outputs": [],
   "source": [
    "%%html\n",
    "<style type=\"text/css\">\n",
    "\n",
    "circle {\n",
    "  fill: rgb(31, 119, 180);\n",
    "  fill-opacity: .25;\n",
    "  stroke: rgb(31, 119, 180);\n",
    "  stroke-width: 1px;\n",
    "}\n",
    "\n",
    ".leaf circle {\n",
    "  fill: #ff7f0e;\n",
    "  fill-opacity: 1;\n",
    "}\n",
    "\n",
    "text {\n",
    "  font: 10px sans-serif;\n",
    "}\n",
    "\n",
    "</style>"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.628049Z",
     "start_time": "2019-07-30T19:54:00.617548Z"
    }
   },
   "outputs": [],
   "source": [
    "%%javascript\n",
    "\n",
    "// element is the jQuery element we will append to\n",
    "var e = element.get(0);\n",
    "    \n",
    "var diameter = 600,\n",
    "    format = d3.format(\",d\");\n",
    "\n",
    "var pack = d3.layout.pack()\n",
    "    .size([diameter - 4, diameter - 4])\n",
    "    .value(function(d) { return d.size; });\n",
    "\n",
    "var svg = d3.select(e).append(\"svg\")\n",
    "    .attr(\"width\", diameter)\n",
    "    .attr(\"height\", diameter)\n",
    "  .append(\"g\")\n",
    "    .attr(\"transform\", \"translate(2,2)\");\n",
    "\n",
    "d3.json(\"data/flare.json\", function(error, root) {\n",
    "  var node = svg.datum(root).selectAll(\".node\")\n",
    "      .data(pack.nodes)\n",
    "    .enter().append(\"g\")\n",
    "      .attr(\"class\", function(d) { return d.children ? \"node\" : \"leaf node\"; })\n",
    "      .attr(\"transform\", function(d) { return \"translate(\" + d.x + \",\" + d.y + \")\"; });\n",
    "\n",
    "  node.append(\"title\")\n",
    "      .text(function(d) { return d.name + (d.children ? \"\" : \": \" + format(d.size)); });\n",
    "\n",
    "  node.append(\"circle\")\n",
    "      .attr(\"r\", function(d) { return d.r; });\n",
    "\n",
    "  node.filter(function(d) { return !d.children; }).append(\"text\")\n",
    "      .attr(\"dy\", \".3em\")\n",
    "      .style(\"text-anchor\", \"middle\")\n",
    "      .text(function(d) { return d.name.substring(0, d.r / 3); });\n",
    "});\n",
    "\n",
    "d3.select(self.frameElement).style(\"height\", diameter + \"px\");"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## LaTeX"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The IPython display system also has builtin support for the display of mathematical expressions typeset in LaTeX, which is rendered in the browser using [MathJax](http://mathjax.org)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can pass raw LaTeX test as a string to the `Math` object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.642029Z",
     "start_time": "2019-07-30T19:54:00.631615Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import Math\n",
    "Math(r'F(k) = \\int_{-\\infty}^{\\infty} f(x) e^{2\\pi i k} dx')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "With the `Latex` class, you have to include the delimiters yourself.  This allows you to use other LaTeX modes such as `eqnarray`:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.668237Z",
     "start_time": "2019-07-30T19:54:00.647288Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import Latex\n",
    "Latex(r\"\"\"\\begin{eqnarray}\n",
    "\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\\n",
    "\\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\\n",
    "\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\\n",
    "\\nabla \\cdot \\vec{\\mathbf{B}} & = 0 \n",
    "\\end{eqnarray}\"\"\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Or you can enter LaTeX directly with the `%%latex` cell magic:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.684882Z",
     "start_time": "2019-07-30T19:54:00.673461Z"
    }
   },
   "outputs": [],
   "source": [
    "%%latex\n",
    "\\begin{align}\n",
    "\\nabla \\times \\vec{\\mathbf{B}} -\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{E}}}{\\partial t} & = \\frac{4\\pi}{c}\\vec{\\mathbf{j}} \\\\\n",
    "\\nabla \\cdot \\vec{\\mathbf{E}} & = 4 \\pi \\rho \\\\\n",
    "\\nabla \\times \\vec{\\mathbf{E}}\\, +\\, \\frac1c\\, \\frac{\\partial\\vec{\\mathbf{B}}}{\\partial t} & = \\vec{\\mathbf{0}} \\\\\n",
    "\\nabla \\cdot \\vec{\\mathbf{B}} & = 0\n",
    "\\end{align}"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Audio"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "IPython makes it easy to work with sounds interactively. The `Audio` display class allows you to create an audio control that is embedded in the Notebook. The interface is analogous to the interface of the `Image` display class. All audio formats supported by the browser can be used. Note that no single format is presently supported in all browsers."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.712314Z",
     "start_time": "2019-07-30T19:54:00.691438Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import Audio\n",
    "Audio(url=\"http://www.nch.com.au/acm/8k16bitpcm.wav\")"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "A NumPy array can be auralized automatically. The `Audio` class normalizes and encodes the data and embeds the resulting audio in the Notebook.\n",
    "\n",
    "For instance, when two sine waves with almost the same frequency are superimposed a phenomena known as [beats](https://en.wikipedia.org/wiki/Beat_%28acoustics%29) occur. This can be auralised as follows:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:00.856617Z",
     "start_time": "2019-07-30T19:54:00.716729Z"
    }
   },
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "max_time = 3\n",
    "f1 = 220.0\n",
    "f2 = 224.0\n",
    "rate = 8000.0\n",
    "L = 3\n",
    "times = np.linspace(0,L,rate*L)\n",
    "signal = np.sin(2*np.pi*f1*times) + np.sin(2*np.pi*f2*times)\n",
    "\n",
    "Audio(data=signal, rate=rate)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Video"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "More exotic objects can also be displayed, as long as their representation supports the IPython display protocol.  For example, videos hosted externally on YouTube are easy to load:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:01.179344Z",
     "start_time": "2019-07-30T19:54:00.860882Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import YouTubeVideo\n",
    "YouTubeVideo('sjfsUzECqK0')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Using the nascent video capabilities of modern browsers, you may also be able to display local\n",
    "videos.  At the moment this doesn't work very well in all browsers, so it may or may not work for you;\n",
    "we will continue testing this and looking for ways to make it more robust.  \n",
    "\n",
    "The following cell loads a local file called  `animation.m4v`, encodes the raw video as base64 for http\n",
    "transport, and uses the HTML5 video tag to load it. On Chrome 15 it works correctly, displaying a control bar at the bottom with a play/pause button and a location slider."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:01.264987Z",
     "start_time": "2019-07-30T19:54:01.186232Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import HTML\n",
    "from base64 import b64encode\n",
    "video = open(\"images/jupyter-basics-animation.m4v\", \"rb\").read()\n",
    "video_encoded = b64encode(video).decode('ascii')\n",
    "video_tag = '<video controls alt=\"test\" src=\"data:video/x-m4v;base64,{0}\">'.format(video_encoded)\n",
    "HTML(data=video_tag)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## External sites"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "You can even embed an entire page from another site in an iframe; for example this is today's Wikipedia\n",
    "page for mobile users:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:01.297437Z",
     "start_time": "2019-07-30T19:54:01.278889Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import IFrame\n",
    "IFrame('http://jupyter.org', width='100%', height=350)"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Links to local files"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "IPython provides builtin display classes for generating links to local files. Create a link to a single file using the `FileLink` object:"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:01.325153Z",
     "start_time": "2019-07-30T19:54:01.306706Z"
    }
   },
   "outputs": [],
   "source": [
    "from IPython.display import FileLink, FileLinks\n",
    "FileLink('Cell Magics.ipynb')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Alternatively, to generate links to all of the files in a directory, use the `FileLinks` object, passing `'.'` to indicate that we want links generated for the current working directory. Note that if there were other directories under the current directory, `FileLinks` would work in a recursive manner creating links to files in all sub-directories as well."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {
    "ExecuteTime": {
     "end_time": "2019-07-30T19:54:01.561308Z",
     "start_time": "2019-07-30T19:54:01.333609Z"
    }
   },
   "outputs": [],
   "source": [
    "FileLinks('.')"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Rich output and security"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "The IPython Notebook allows arbitrary code execution in both the IPython kernel and in the browser, though HTML and JavaScript output. More importantly, because IPython has a JavaScript API for running code in the browser, HTML and JavaScript output can actually trigger code to be run in the kernel. This poses a significant security risk as it would allow IPython Notebooks to execute arbitrary code on your computers.\n",
    "\n",
    "To protect against these risks, the IPython Notebook has a security model that specifies how dangerous output is handled. Here is a short summary:\n",
    "\n",
    "* When you run code in the Notebook, all rich output is displayed.\n",
    "* When you open a notebook, rich output is only displayed if it doesn't contain security vulberabilities, ...\n",
    "* ... or if you have trusted a notebook, all rich output will run upon opening it.\n",
    "\n",
    "A full description of the IPython security model can be found on [this page](http://ipython.org/ipython-doc/dev/notebook/security.html)."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## Rich output and nbviewer"
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Much of the power of the Notebook is that it enables users to share notebooks with each other using http://nbviewer.ipython.org, without installing IPython locally. As of IPython 2.0, notebooks rendered on nbviewer will display all output, including HTML and JavaScript. Furthermore, to provide a consistent JavaScript environment on the live Notebook and nbviewer, the following JavaScript libraries are loaded onto the nbviewer page, *before* the notebook and its output is displayed:\n",
    "\n",
    "* [jQuery](http://jquery.com/)\n",
    "* [RequireJS](http://requirejs.org/)\n",
    "\n",
    "Libraries such as [mpld3](http://mpld3.github.io/) use these capabilities to generate interactive visualizations that work on nbviewer."
   ]
  },
  {
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "# Next Steps\n",
    "\n",
    "- [Python Basics](./python-basics-tutorial.ipynb): Learn the basics about python data types.\n",
    "- [Jupyter Tipps & Tricks](./jupyter-tipps.ipynb): Explore some amazing functionalities that you can use with Jupyter within the workspace.\n",
    "- [Visualization in Jupyter](./visualization-tutorial.ipynb): Introduction to data visualization with various common charting tools.\n",
    "- [Introduction to Pandas](./pandas-tutorial.ipynb): Introduction to the data structures and functionalities of the pandas library."
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.6.8"
  },
  "toc": {
   "base_numbering": 1,
   "nav_menu": {},
   "number_sections": true,
   "sideBar": true,
   "skip_h1_title": false,
   "title_cell": "Table of Contents",
   "title_sidebar": "Contents",
   "toc_cell": false,
   "toc_position": {},
   "toc_section_display": true,
   "toc_window_display": true
  },
  "varInspector": {
   "cols": {
    "lenName": 16,
    "lenType": 16,
    "lenVar": 40
   },
   "kernels_config": {
    "python": {
     "delete_cmd_postfix": "",
     "delete_cmd_prefix": "del ",
     "library": "var_list.py",
     "varRefreshCmd": "print(var_dic_list())"
    },
    "r": {
     "delete_cmd_postfix": ") ",
     "delete_cmd_prefix": "rm(",
     "library": "var_list.r",
     "varRefreshCmd": "cat(var_dic_list()) "
    }
   },
   "types_to_exclude": [
    "module",
    "function",
    "builtin_function_or_method",
    "instance",
    "_Feature"
   ],
   "window_display": false
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
